Docker Compose Network 配置笔记
是的,即使两个服务不写在同一个 Docker Compose 配置文件中,也可以实现隔离。这种情况下,可以通过 自定义网络 来实现服务之间的隔离或互通。
以下是如何在两个独立的 Docker Compose 配置文件中实现隔离的详细说明:
方法 1:完全隔离(不同网络)
如果两个服务完全独立,且不需要互相通信,可以将它们放在不同的 Docker 网络中:
配置文件 1 (docker-compose-service1.yml)
version: '3.9'
services:
app_service1:
image: my_app_service1_image # 替换为第一个服务的镜像
networks:
- network_service1
environment:
DATABASE_HOST: postgres_service1
DATABASE_PORT: 5432
DATABASE_USER: user1
DATABASE_PASSWORD: password1
DATABASE_NAME: db1
postgres_service1:
image: postgres:latest
container_name: postgres_service1
networks:
- network_service1
environment:
POSTGRES_USER: user1
POSTGRES_PASSWORD: password1
POSTGRES_DB: db1
ports:
- "5432:5432" # 可选:仅在需要从宿主机访问时映射端口
networks:
network_service1:
driver: bridge
配置文件 2 (docker-compose-service2.yml)
version: '3.9'
services:
app_service2:
image: my_app_service2_image # 替换为第二个服务的镜像
networks:
- network_service2
environment:
DATABASE_HOST: postgres_service2
DATABASE_PORT: 5432
DATABASE_USER: user2
DATABASE_PASSWORD: password2
DATABASE_NAME: db2
postgres_service2:
image: postgres:latest
container_name: postgres_service2
networks:
- network_service2
environment:
POSTGRES_USER: user2
POSTGRES_PASSWORD: password2
POSTGRES_DB: db2
ports:
- "5433:5432" # 可选:仅在需要从宿主机访问时映射端口
networks:
network_service2:
driver: bridge
启动服务
分别在两个配置文件所在的目录运行以下命令:
docker-compose -f docker-compose-service1.yml up -d
docker-compose -f docker-compose-service2.yml up -d
效果
- 两个服务被放在不同的网络中,完全隔离,无法直接通信。
- 如果需要从宿主机访问 PostgreSQL,可以通过
5432访问postgres_service1,通过5433访问postgres_service2。
方法 2:部分隔离(共享网络)
如果两个服务需要部分隔离,但仍需要通过网络通信,可以让它们共享一个 自定义网络。
创建共享网络
首先,创建一个共享网络:
docker network create shared_network
配置文件 1 (docker-compose-service1.yml)
version: '3.9'
services:
app_service1:
image: my_app_service1_image
networks:
- shared_network
environment:
DATABASE_HOST: postgres_service1
DATABASE_PORT: 5432
DATABASE_USER: user1
DATABASE_PASSWORD: password1
DATABASE_NAME: db1
postgres_service1:
image: postgres:latest
container_name: postgres_service1
networks:
- shared_network
environment:
POSTGRES_USER: user1
POSTGRES_PASSWORD: password1
POSTGRES_DB: db1
ports:
- "5432:5432"
networks:
shared_network:
external: true
配置文件 2 (docker-compose-service2.yml)
version: '3.9'
services:
app_service2:
image: my_app_service2_image
networks:
- shared_network
environment:
DATABASE_HOST: postgres_service2
DATABASE_PORT: 5432
DATABASE_USER: user2
DATABASE_PASSWORD: password2
DATABASE_NAME: db2
postgres_service2:
image: postgres:latest
container_name: postgres_service2
networks:
- shared_network
environment:
POSTGRES_USER: user2
POSTGRES_PASSWORD: password2
POSTGRES_DB: db2
ports:
- "5433:5432"
networks:
shared_network:
external: true
启动服务
分别在两个配置文件所在的目录运行以下命令:
docker-compose -f docker-compose-service1.yml up -d
docker-compose -f docker-compose-service2.yml up -d
效果
- 两个服务共享同一个网络
shared_network,可以通过容器名(如postgres_service1或postgres_service2)相互通信。 - 宿主机仍然可以通过
5432和5433访问两个 PostgreSQL 实例。
方法 3:动态网络(无需预先创建网络)
如果不想手动创建网络,可以在两个配置文件中定义相同名称的网络,Docker Compose 会自动将它们加入同一个网络。
配置文件 1 (docker-compose-service1.yml)
version: '3.9'
services:
app_service1:
image: my_app_service1_image
networks:
- common_network
environment:
DATABASE_HOST: postgres_service1
DATABASE_PORT: 5432
DATABASE_USER: user1
DATABASE_PASSWORD: password1
DATABASE_NAME: db1
postgres_service1:
image: postgres:latest
container_name: postgres_service1
networks:
- common_network
environment:
POSTGRES_USER: user1
POSTGRES_PASSWORD: password1
POSTGRES_DB: db1
ports:
- "5432:5432"
networks:
common_network:
name: shared_network
driver: bridge
配置文件 2 (docker-compose-service2.yml)
version: '3.9'
services:
app_service2:
image: my_app_service2_image
networks:
- common_network
environment:
DATABASE_HOST: postgres_service2
DATABASE_PORT: 5432
DATABASE_USER: user2
DATABASE_PASSWORD: password2
DATABASE_NAME: db2
postgres_service2:
image: postgres:latest
container_name: postgres_service2
networks:
- common_network
environment:
POSTGRES_USER: user2
POSTGRES_PASSWORD: password2
POSTGRES_DB: db2
ports:
- "5433:5432"
networks:
common_network:
name: shared_network
driver: bridge
启动服务
分别在两个配置文件所在的目录运行以下命令:
docker-compose -f docker-compose-service1.yml up -d
docker-compose -f docker-compose-service2.yml up -d
效果
- 两个服务共享网络
shared_network,可以通过容器名相互通信。 - Docker Compose 会自动创建
shared_network,无需手动创建。
这段代码是 Docker Compose 文件中定义网络的部分,涉及到两个自定义网络的配置:docker-internal 和 internet。以下是对这段代码的详细说明:
代码结构
networks:
docker-internal:
driver: bridge
internal: true
internet:
driver: bridge
详细解释
1. networks
networks是 Docker Compose 文件中定义自定义网络的顶级关键字。- 它允许为服务创建和配置专属的网络,以便服务之间可以通信,同时可以控制是否允许访问外部网络(如互联网)。
2. docker-internal
docker-internal:
driver: bridge
internal: true
-
driver: bridge:- 指定网络使用的是 Docker 的 桥接网络(bridge network) 模式。
- 这是 Docker 的默认网络驱动类型,适合在单个宿主机上运行的容器之间通信。
- 每个桥接网络是独立的,容器只能与同一个网络中的其他容器通信。
-
internal: true:- 这是一个关键配置,表示该网络是 内部网络。
- 内部网络的特点是 禁止容器访问宿主机网络和外部互联网。
- 任何连接到该网络的容器只能与同一网络中的其他容器通信,无法访问外部网络(例如,无法连接到互联网或宿主机的其他服务)。
- 适合用于隔离敏感的服务,例如数据库、缓存服务等,确保这些服务只能被内部的应用程序访问,而不会暴露给外界。
应用场景
- 将数据库服务(例如 PostgreSQL、MySQL 等)放置在
docker-internal网络中,确保数据库服务无法直接访问互联网,避免安全风险。 - 例如:
- 数据库服务连接到
docker-internal。 - 应用服务同时连接到
docker-internal和其他网络(如internet),从而实现对数据库的访问。
- 数据库服务连接到
3. internet
internet:
driver: bridge
driver: bridge:- 同样使用桥接网络模式。
- 这是一个普通的桥接网络,没有设置
internal: true,因此默认允许容器访问宿主机网络和互联网。
应用场景
- 将需要访问互联网的服务(例如应用服务、API 网关等)放置在
internet网络中。 - 适用于需要访问外部资源(如第三方 API、远程服务器)的服务。
如何使用这些网络
在 Docker Compose 文件中定义了网络后,可以通过 networks 配置将服务加入到对应的网络。例如:
version: '3.9'
services:
app:
image: my_app_image
networks:
- docker-internal # 应用程序可以访问数据库
- internet # 应用程序也可以访问互联网
depends_on:
- db
db:
image: postgres:latest
networks:
- docker-internal # 数据库只能被内部服务访问
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: example_db
networks:
docker-internal:
driver: bridge
internal: true
internet:
driver: bridge
示例说明
服务通信
db服务(数据库)连接到docker-internal网络,因此它无法访问互联网,也无法直接与internet网络中的其他容器通信。app服务连接到两个网络:- 通过
docker-internal网络可以访问db服务。 - 通过
internet网络可以访问互联网。
- 通过
网络隔离的好处
- 数据库服务(
db)不会暴露给外部网络,提升了安全性。 - 应用服务(
app)可以同时访问数据库和互联网,满足业务需求。
总结
-
docker-internal网络:- 使用
internal: true禁止网络访问外部互联网。 - 适用于需要隔离的服务,例如数据库、缓存服务等。
- 使用
-
internet网络:- 普通桥接网络,允许容器访问互联网。
- 适用于需要对外通信的服务,例如应用服务、API 服务等。
通过这种方式,可以灵活地控制容器的网络访问权限,确保服务的隔离性和安全性,同时满足业务需求。